﻿const pad2 = value => {
  const num = typeof value === "number" ? value : parseInt(value, 10);
  if (Number.isNaN(num)) return "00";
  return num < 10 ? `0${num}` : `${num}`;
};

const toDate = source => {
  if (!source) return null;

  if (source instanceof Date) {
    return Number.isNaN(source.getTime()) ? null : source;
  }

  if (typeof source === "object" && source.$date) {
    return toDate(source.$date);
  }

  let normalized = source;
  if (typeof source === "string") {
    normalized = source.trim();
    if (/^\d+$/.test(normalized)) {
      const timestamp = Number(normalized);
      return Number.isNaN(timestamp) ? null : new Date(timestamp);
    }
    normalized = normalized.replace(/\//g, "-");
    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2})?$/.test(normalized)) {
      normalized = normalized.replace(" ", "T");
    }
    if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(normalized)) {
      normalized = `${normalized}:00`;
    }
    if (/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
      normalized = `${normalized}T00:00:00`;
    }
  }

  const result = new Date(normalized);
  return Number.isNaN(result.getTime()) ? null : result;
};

const formatDate = date => {
  if (!date) return "";
  const year = date.getFullYear();
  const month = pad2(date.getMonth() + 1);
  const day = pad2(date.getDate());
  const hour = pad2(date.getHours());
  const minute = pad2(date.getMinutes());
  return `${year}年${month}月${day}日 ${hour}:${minute}`;
};

const formatDateTime = value => {
  const date = toDate(value);
  if (!date) return "";
  const year = date.getFullYear();
  const month = pad2(date.getMonth() + 1);
  const day = pad2(date.getDate());
  const hour = pad2(date.getHours());
  const minute = pad2(date.getMinutes());
  return `${year}-${month}-${day} ${hour}:${minute}`;
};

const formatRange = (start, end) => {
  const startText = start ? formatDate(start) : "";
  const endText = end ? formatDate(end) : "";
  if (startText && endText) return `${startText} - ${endText}`;
  return startText || endText || "";
};

const normalizeString = value => (typeof value === "string" ? value.trim() : "");

const decodeHTML = value => {
  if (value === null || value === undefined) return "";
  let text = String(value);

  const decodeCodePoint = code => {
    if (!Number.isFinite(code) || code < 0) return "";
    try {
      return typeof String.fromCodePoint === "function"
        ? String.fromCodePoint(code)
        : String.fromCharCode(code);
    } catch (error) {
      return "";
    }
  };

  const namedEntities = {
    "&nbsp;": " ",
    "&lt;": "<",
    "&gt;": ">",
    "&quot;": "\"",
    "&#39;": "'"
  };

  const decodeOnce = source => {
    let result = source.replace(/&amp;/g, "&");

    result = result.replace(/&#x([0-9a-fA-F]+);?/g, (match, hex) => {
      const code = parseInt(hex, 16);
      const char = decodeCodePoint(code);
      return char || match;
    });

    result = result.replace(/&#(\d+);?/g, (match, dec) => {
      const code = parseInt(dec, 10);
      const char = decodeCodePoint(code);
      return char || match;
    });

    Object.keys(namedEntities).forEach(entity => {
      const replacement = namedEntities[entity];
      if (replacement !== undefined) {
        result = result.replace(new RegExp(entity, "g"), replacement);
      }
    });

    return result;
  };

  for (let i = 0; i < 5; i += 1) {
    const decoded = decodeOnce(text);
    if (decoded === text) break;
    text = decoded;
  }

  return text;
};

const formatGenderDisplay = value => {
  if (value === null || value === undefined || value === "") return "";
  if (typeof value === "number") {
    if (value === 1) return "男";
    if (value === 2) return "女";
    return String(value);
  }
  const text = normalizeString(value);
  if (!text) return "";
  if (text === "男" || text === "女") return text;
  const lower = text.toLowerCase();
  if (lower === "1" || lower === "male" || lower === "m") return "男";
  if (lower === "2" || lower === "female" || lower === "f") return "女";
  return text;
};

const STUDENT_TYPE_LABELS = {
  1: "本科生",
  2: "硕士研究生",
  3: "博士研究生"
};

const formatStudentTypeDisplay = value => {
  if (value === null || value === undefined || value === "") return "";
  if (typeof value === "number") return STUDENT_TYPE_LABELS[value] || String(value);
  const text = normalizeString(value);
  if (!text) return "";
  if (/^[123]$/.test(text)) {
    const numberValue = Number(text);
    return STUDENT_TYPE_LABELS[numberValue] || text;
  }
  const lower = text.toLowerCase();
  if (text.includes("本科") || lower.includes("undergraduate")) {
    return STUDENT_TYPE_LABELS[1];
  }
  if (
    text.includes("硕") ||
    text.includes("研") ||
    lower.includes("master") ||
    lower.includes("postgraduate") ||
    lower.includes("graduate")
  ) {
    return STUDENT_TYPE_LABELS[2];
  }
  if (
    text.includes("博") ||
    lower.includes("phd") ||
    lower.includes("doctor") ||
    lower.includes("doctoral")
  ) {
    return STUDENT_TYPE_LABELS[3];
  }
  return text;
};

const formatEnrollmentYearDisplay = value => {
  if (value === null || value === undefined || value === "") return "";
  if (value instanceof Date && !Number.isNaN(value.getTime())) {
    const year = value.getFullYear();
    return year ? `${year}级` : "";
  }
  if (typeof value === "number") {
    if (value >= 1900 && value <= 2100) return `${value}级`;
    return String(value);
  }
  const text = normalizeString(value);
  if (!text) return "";
  const match = text.match(/\d{4}/);
  if (match) return `${match[0]}级`;
  return text;
};

const createDetailModalState = (overrides = {}) =>
  Object.assign(
    {
      visible: false,
      loading: false,
      error: "",
      registrant: null,
      expandedSections: {
        groups: true,
        fields: false
      },
      deleting: false
    },
    overrides
  );

Page({
  data: {
    mode: "registrants",
    loading: true,
    errorMessage: "",
    activityID: "",
    activityName: "",
    isPublisher: false,
    // registrants
    groups: [],
    totalRegistrants: 0,
    // check-in specific
    activeGroupID: "",
    activeGroupIndex: 0,
    activeGroupName: "",
    activeGroupTime: "",
    activeGroupRemark: "",
    activeTab: "checkIn",
    checkInLoading: false,
    checkInError: "",
    checkInSummary: {
      checkInCount: 0,
      checkOutCount: 0
    },
    displayList: [],
    detailModal: createDetailModalState()
  },
  isCurrentUserPublisher(openID) {
    if (!openID) return false;
    const app = typeof getApp === "function" ? getApp() : null;
    const globalUser = (app && app.globalData && app.globalData.userInfo) || {};
    const currentOpenID = globalUser.openID || (app && app.globalData && app.globalData.openID) || "";
    return !!currentOpenID && openID === currentOpenID;
  },
  onLoad(options = {}) {
    const mode = options.mode === "checkin" ? "checkin" : "registrants";
    const activityID = options.activityID || options.activityId || options.id || "";
    const initialGroupID = options.groupID || options.groupId || "";
    if (!activityID) {
      this.setData({
        loading: false,
        errorMessage: "缺少活动编号，无法加载成员列表"
      });
      return;
    }

    this.setNavigationTitle(mode);

    this.setData({
      mode,
      activityID
    });

    this.loadActivityInfo(activityID)
      .then(activity => {
        if (!activity) {
          throw new Error("未找到活动信息");
        }
        const activityName = normalizeString(activity.activityName) || "活动成员";
        const isPublisher = this.isCurrentUserPublisher(activity.publisherOpenID);
        this.setData({
          activityName,
          isPublisher
        });

        if (mode === "registrants") {
          return this.loadRegistrants(activity, initialGroupID);
        }
        return this.prepareCheckIn(activity, initialGroupID);
      })
      .catch(error => {
        const message = this.normalizeError(error, "成员信息加载失败，请稍后再试");
        this.setData({
          loading: false,
          checkInLoading: false,
          errorMessage: message,
          checkInError: message
        });
      });
  },

  setNavigationTitle(mode) {
    const title = mode === "checkin" ? "签到人员" : "报名人员";
    wx.setNavigationBarTitle({ title });
  },

  normalizeError(error, fallback) {
    if (typeof error === "string" && error.trim()) return error;
    if (error && typeof error.message === "string" && error.message.trim()) return error.message;
    if (error && typeof error.errMsg === "string" && error.errMsg.trim()) return error.errMsg;
    return fallback;
  },

  callFunction(options = {}) {
    const app = typeof getApp === "function" ? getApp() : null;
    if (app && typeof app.callCloudFunction === "function") {
      return new Promise((resolve, reject) => {
        const { success, fail, complete } = options;
        app.callCloudFunction(
          Object.assign({}, options, {
            success: res => {
              if (typeof success === "function") {
                try {
                  success(res);
                } catch (error) {
                  console.error("callFunction success 回调异常", error);
                }
              }
              resolve(res);
            },
            fail: err => {
              if (typeof fail === "function") {
                try {
                  fail(err);
                } catch (error) {
                  console.error("callFunction fail 回调异常", error);
                }
              }
              reject(err);
            },
            complete: (...args) => {
              if (typeof complete === "function") {
                try {
                  complete(...args);
                } catch (error) {
                  console.error("callFunction complete 回调异常", error);
                }
              }
            }
          })
        );
      });
    }

    const { name, data = {}, loadingTitle, showLoading = true } = options;
    const title =
      typeof loadingTitle === "string" && loadingTitle.trim() ? loadingTitle.trim() : "加载中...";
    const shouldShow = showLoading !== false;

    if (shouldShow) {
      wx.showLoading({ title, mask: true });
    }

    return new Promise((resolve, reject) => {
      wx.cloud.callFunction({
        name,
        data,
        success: res => resolve(res),
        fail: err => reject(err),
        complete: () => {
          if (shouldShow) {
            wx.hideLoading();
          }
        }
      });
    });
  },

  loadActivityInfo(activityID) {
    return this.callFunction({
      name: "queryActivityInfo",
      data: { activityID },
      loadingTitle: "加载活动信息..."
    }).then(res => {
      const payload = (res && (res.result || res.data)) || res;
      if (!payload || payload.error) {
        throw new Error(payload && payload.error ? payload.error : "活动信息加载失败");
      }
      return payload;
    });
  },

  loadRegistrants(activity, initialGroupID = "") {
    const activityGroups = Array.isArray(activity.activityGroups) ? activity.activityGroups : [];
    const activityID = activity.activityID || activity.activityId || this.data.activityID;

    this.setData({
      loading: true,
      errorMessage: ""
    });

    return this.callFunction({
      name: "queryRegistrants",
      data: { activityID },
      loadingTitle: "获取报名名单..."
    })
      .then(res => {
        const payload = res && (res.result || res.data || res);
        if (!payload || !payload.success || !payload.data) {
          throw new Error(
            (payload && (payload.error || payload.message)) || "报名名单获取失败，请稍后再试"
          );
        }

        const registrants = Array.isArray(payload.data.registrants)
          ? payload.data.registrants
          : [];

        const groups = this.mergeRegistrantData(activityGroups, registrants, initialGroupID);
        const total = groups.reduce((sum, group) => sum + (group.count || 0), 0);

        this.setData({
          loading: false,
          errorMessage: "",
          groups,
          totalRegistrants: total
        });
      })
      .catch(error => {
        const message = this.normalizeError(error, "报名名单加载失败，请稍后重试");
        this.setData({
          loading: false,
          errorMessage: message
        });
      });
  },

  mergeRegistrantData(activityGroups, registrants, initialGroupID = "") {
    const groupsMap = new Map();

    const ensureGroup = (groupID, defaults = {}) => {
      if (!groupID) return null;
      if (!groupsMap.has(groupID)) {
        groupsMap.set(
          groupID,
          Object.assign(
            {
              groupID,
              groupName: "未命名分组",
              timeDisplay: "",
              remark: "",
              quota: 0,
              quotaText: "",
              count: 0,
              countDisplay: "0",
              registrants: [],
              expanded: false
            },
            defaults
          )
        );
      }
      return groupsMap.get(groupID);
    };

    activityGroups.forEach((group, index) => {
      const groupID = group.groupID || group._id || group.GroupID || "";
      if (!groupID) return;
      const start = toDate(group.groupStartTime || group.GroupStartTime || group.startTime);
      const end = toDate(group.groupEndTime || group.GroupEndTime || group.endTime);
      const quota =
        typeof group.groupRegistrationCount === "number"
          ? group.groupRegistrationCount
          : typeof group.GroupRegistrationCount === "number"
          ? group.GroupRegistrationCount
          : 0;
      const remark = decodeHTML(group.remark || group.Remark || "");
      ensureGroup(groupID, {
        groupName: group.groupName || group.GroupName || `分组 ${index + 1}`,
        timeDisplay: formatRange(start, end),
        remark,
        quota
      });
    });

    registrants.forEach(person => {
      const openID = person.openID || person.OpenID || "";
      const name = normalizeString(person.name || person.Nickname || "未填写");
      const studentID = normalizeString(person.studentID || person.StudentID || "");
      const groups = Array.isArray(person.groups) ? person.groups : [];
      groups.forEach(groupInfo => {
        const groupID = groupInfo.groupID || groupInfo.GroupID || "";
        if (!groupID) return;
        const record = ensureGroup(groupID, {
          groupName: groupInfo.groupName || groupInfo.GroupName || "未命名分组"
        });
        if (!record) return;
        const registrationTime =
          groupInfo.registrationTime || groupInfo.RegistrationTime || groupInfo.time || "";
        const timeDisplay = registrationTime ? formatDateTime(registrationTime) : "";
        const member = {
          key: `${groupID}-${record.registrants.length}`,
          openID,
          name,
          studentID,
          registrationTime,
          registrationTimeDisplay: timeDisplay
        };
        record.registrants.push(member);
      });
    });

    const result = Array.from(groupsMap.values());
    result.forEach(group => {
      group.registrants.sort((a, b) => {
        const dateA = toDate(a.registrationTime);
        const dateB = toDate(b.registrationTime);
        const valueA = dateA ? dateA.getTime() : 0;
        const valueB = dateB ? dateB.getTime() : 0;
        return valueA - valueB;
      });
      group.count = group.registrants.length;
      const quota = typeof group.quota === "number" ? group.quota : 0;
      group.countDisplay = quota > 0 ? `${group.count}/${quota}` : `${group.count}`;
      group.quotaText = quota > 0 ? `${group.count}/${quota}` : "不限";
      group.expanded = false;
    });

    result.sort((a, b) => {
      const nameA = a.groupName || "";
      const nameB = b.groupName || "";
      return nameA.localeCompare(nameB);
    });

    if (result.length > 0) {
      const targetID = result.some(group => group.groupID === initialGroupID)
        ? initialGroupID
        : result[0].groupID;
      result.forEach(group => {
        group.expanded = group.groupID === targetID;
      });
    }

    return result;
  },

  handleGroupHeaderTap(event) {
    const dataset = event && event.currentTarget ? event.currentTarget.dataset : {};
    const groupID = dataset && dataset.groupId ? dataset.groupId : "";
    if (!groupID) return;
    const groups = this.data.groups.slice();
    const target = groups.find(item => item.groupID === groupID);
    if (!target) return;
    target.expanded = !target.expanded;
    this.setData({ groups });
  },

  prepareCheckIn(activity, initialGroupID = "") {
    const activityGroups = Array.isArray(activity.activityGroups) ? activity.activityGroups : [];
    if (activityGroups.length === 0) {
      this.setData({
        loading: false,
        errorMessage: "",
        groups: [],
        activeGroupID: "",
        displayList: [],
        checkInLoading: false,
        checkInError: "暂无可用分组"
      });
      return Promise.resolve();
    }

    const groups = activityGroups.map((group, index) => {
      const groupID = group.groupID || group._id || group.GroupID || "";
      const start = toDate(group.groupStartTime || group.GroupStartTime || group.startTime);
      const end = toDate(group.groupEndTime || group.GroupEndTime || group.endTime);
      return {
        groupID,
        groupName: group.groupName || group.GroupName || `分组 ${index + 1}`,
        timeDisplay: formatRange(start, end),
        remark: decodeHTML(group.remark || group.Remark || ""),
        checkInRegistrants: [],
        checkOutRegistrants: [],
        checkInCount: 0,
        checkOutCount: 0,
        loaded: false
      };
    });

    const availableGroups = groups.filter(group => !!group.groupID);
    if (!availableGroups.length) {
      this.setData({
        loading: false,
        errorMessage: "",
        groups: [],
        activeGroupID: "",
        displayList: [],
        checkInLoading: false,
        checkInError: "暂无可用分组"
      });
      return Promise.resolve();
    }

    const targetGroupID = availableGroups.some(group => group.groupID === initialGroupID)
      ? initialGroupID
      : availableGroups[0].groupID;
    const activeGroupIndex = availableGroups.findIndex(group => group.groupID === targetGroupID);

    this.setData(
      {
        groups: availableGroups,
        loading: false,
        errorMessage: "",
        activeGroupID: targetGroupID,
        activeGroupIndex: activeGroupIndex >= 0 ? activeGroupIndex : 0,
        activeTab: "checkIn",
        checkInLoading: true,
        checkInError: ""
      },
      () => {
        if (targetGroupID) {
          this.loadCheckInGroup(targetGroupID);
        } else {
          this.setData({
            checkInLoading: false,
            checkInError: "暂无可用分组"
          });
        }
      }
    );

    return Promise.resolve();
  },

  loadCheckInGroup(groupID) {
    if (!groupID) {
      this.setData({
        checkInLoading: false,
        checkInError: "缺少分组信息"
      });
      return Promise.resolve();
    }

    this.setData({
      checkInLoading: true,
      checkInError: ""
    });

    return this.callFunction({
      name: "queryRegistrantCheckInInfo",
      data: { groupID },
      loadingTitle: "获取签到名单...",
      showLoading: false
    })
      .then(res => {
        const payload = res && (res.result || res.data || res);
        if (!payload || !payload.success) {
          throw new Error(
            (payload && (payload.error || payload.message)) || "获取签到名单失败，请稍后再试"
          );
        }

        const checkInRaw = Array.isArray(payload.checkInRegistrants)
          ? payload.checkInRegistrants
          : [];
        const checkOutRaw = Array.isArray(payload.checkOutRegistrants)
          ? payload.checkOutRegistrants
          : [];

        const normalizeList = (list, timeKey) =>
          list.map((item, index) => {
            const openID = item.openID || item.OpenID || "";
            const name = normalizeString(item.name || item.Nickname || "未填写");
            const studentID = normalizeString(item.studentID || item.StudentID || "");
            const timeValue =
              item[timeKey] !== undefined && item[timeKey] !== null
                ? item[timeKey]
                : timeKey === "checkInTime"
                ? item.checkInTime || item.time || ""
                : item.checkOutTime || item.time || "";
            const timeDisplay = timeValue ? formatDateTime(timeValue) : "";
            return {
              key: `${timeKey}-${index}`,
              openID,
              name,
              studentID,
              timeDisplay
            };
          });

        const checkInList = normalizeList(checkInRaw, "checkInTime");
        const checkOutList = normalizeList(checkOutRaw, "checkOutTime");

        const groups = this.data.groups.slice();
        const targetIndex = groups.findIndex(group => group.groupID === groupID);
        if (targetIndex >= 0) {
          groups[targetIndex] = Object.assign({}, groups[targetIndex], {
            checkInRegistrants: checkInList,
            checkOutRegistrants: checkOutList,
            checkInCount: checkInList.length,
            checkOutCount: checkOutList.length,
            loaded: true
          });
        }

        this.setData(
          {
            groups,
            checkInLoading: false,
            checkInError: ""
          },
          () => {
            this.updateDisplayList();
          }
        );
      })
      .catch(error => {
        const message = this.normalizeError(error, "签到名单加载失败，请稍后重试");
        this.setData({
          checkInLoading: false,
          checkInError: message
        });
      });
  },

  updateDisplayList() {
    const { groups, activeGroupID, activeTab } = this.data;
    const target = groups.find(group => group.groupID === activeGroupID);
    if (!target) {
      this.setData({
        activeGroupName: "",
        activeGroupTime: "",
        activeGroupRemark: "",
        checkInSummary: { checkInCount: 0, checkOutCount: 0 },
        displayList: []
      });
      return;
    }

    const checkInCount = Array.isArray(target.checkInRegistrants)
      ? target.checkInRegistrants.length
      : target.checkInCount || 0;
    const checkOutCount = Array.isArray(target.checkOutRegistrants)
      ? target.checkOutRegistrants.length
      : target.checkOutCount || 0;

    const list =
      activeTab === "checkOut"
        ? target.checkOutRegistrants || []
        : target.checkInRegistrants || [];

    this.setData({
      activeGroupName: target.groupName || "",
      activeGroupTime: target.timeDisplay || "",
      activeGroupRemark: target.remark || "",
      checkInSummary: {
        checkInCount,
        checkOutCount
      },
      displayList: list
    });
  },

  handleGroupPickerChange(event) {
    const value = event && event.detail ? event.detail.value : "";
    const index = typeof value === "number" ? value : parseInt(value, 10);
    if (Number.isNaN(index)) return;
    const groups = this.data.groups || [];
    if (index < 0 || index >= groups.length) return;
    const group = groups[index];
    if (!group || !group.groupID) return;

    this.setData(
      {
        activeGroupID: group.groupID,
        activeGroupIndex: index,
        activeTab: "checkIn",
        checkInError: ""
      },
      () => {
        if (!group.loaded) {
          this.loadCheckInGroup(group.groupID);
        } else {
          this.updateDisplayList();
        }
      }
    );
  },

  handleCheckInTabTap(event) {
    const dataset = event && event.currentTarget ? event.currentTarget.dataset : {};
    const tab = dataset && dataset.tab ? dataset.tab : "";
    if (!tab || (tab !== "checkIn" && tab !== "checkOut")) return;
    if (tab === this.data.activeTab) return;
    this.setData(
      {
        activeTab: tab
      },
      () => {
        this.updateDisplayList();
      }
    );
  },

  handleMemberTap(event) {
    const dataset = event && event.currentTarget ? event.currentTarget.dataset : {};
    const openID = dataset && dataset.openId ? String(dataset.openId) : "";
    if (!openID) return;

    const activityID = this.data.activityID;
    if (!activityID) return;

    const baseInfo = {
      openID,
      name: dataset && dataset.name ? dataset.name : "",
      studentID: dataset && dataset.studentId ? dataset.studentId : "",
      groupID: dataset && dataset.groupId ? String(dataset.groupId) : "",
      groupName: dataset && dataset.groupName ? dataset.groupName : "",
      timeDisplay: dataset && dataset.timeDisplay ? dataset.timeDisplay : ""
    };

    this.setData({
      detailModal: createDetailModalState({
        visible: true,
        loading: true,
        registrant: baseInfo
      })
    });

    this.callFunction({
      name: "queryRegistrationInfo",
      data: { activityID, targetOpenID: openID },
      loadingTitle: "获取报名信息...",
      showLoading: false
    })
      .then(res => {
        const payload = res && (res.result || res.data || res);
        if (!payload || !payload.success || !payload.data) {
          const message =
            (payload && (payload.error || payload.message)) || "报名信息获取失败，请稍后重试";
          this.setData({
            detailModal: createDetailModalState({
              visible: true,
              loading: false,
              error: message,
              registrant: baseInfo
            })
          });
          return;
        }

        const registrant = Object.assign({}, baseInfo, this.normalizeRegistrantDetail(payload.data));

        const hasGroups =
          Array.isArray(registrant.registrationGroups) && registrant.registrationGroups.length > 0;
        const hasFields =
          Array.isArray(registrant.registrationFields) && registrant.registrationFields.length > 0;

        this.setData({
          detailModal: createDetailModalState({
            visible: true,
            loading: false,
            error: "",
            registrant,
            expandedSections: {
              groups: hasGroups,
              fields: hasFields
            },
            deleting: false
          })
        });
      })
      .catch(error => {
        const message = this.normalizeError(error, "报名信息获取失败，请稍后重试");
        this.setData({
          detailModal: createDetailModalState({
            visible: true,
            loading: false,
            error: message,
            registrant: baseInfo
          })
        });
      });
  },

  normalizeRegistrantDetail(detail = {}) {
    const result = Object.assign(
      {
        name: "",
        gender: "",
        studentID: "",
        studentType: "",
        grade: "",
        college: "",
        major: "",
        phoneNumber: "",
        registrationGroups: [],
        registrationFields: []
      },
      detail
    );

    const groupMap = new Map();
    const groups = Array.isArray(this.data.groups) ? this.data.groups : [];
    groups.forEach(group => {
      if (group && group.groupID) {
        groupMap.set(group.groupID, group);
      }
    });

    if (Array.isArray(result.registrationGroups)) {
      result.registrationGroups = result.registrationGroups.map(item => {
        const groupID =
          item.groupID || item.GroupID || item.groupId || item.GroupId || item.id || "";
        const meta = groupMap.get(groupID) || {};
        const start = toDate(
          item.GroupStartTime ||
            item.groupStartTime ||
            item.startTime ||
            (meta && meta.startTime) ||
            null
        );
        const end = toDate(
          item.GroupEndTime ||
            item.groupEndTime ||
            item.endTime ||
            (meta && meta.endTime) ||
            null
        );
        return {
          groupID,
          groupName: item.groupName || item.GroupName || meta.groupName || "",
          timeDisplay: meta.timeDisplay || formatRange(start, end)
        };
      });
    } else {
      result.registrationGroups = [];
    }

    if (!Array.isArray(result.registrationFields)) {
      result.registrationFields = [];
    } else {
      result.registrationFields = result.registrationFields.map(item => {
        const fieldID =
          item.fieldID || item.FieldID || item.fieldId || item.FieldId || item.id || "";
        return {
          fieldID,
          fieldName: item.fieldName || item.FieldName || "",
          fieldContent: item.fieldContent || item.FieldContent || item.content || ""
        };
      });
    }

    result.gender = formatGenderDisplay(result.gender);
    result.studentType = formatStudentTypeDisplay(result.studentType);
    result.grade = formatEnrollmentYearDisplay(result.grade);

    return result;
  },

  handleMemberDetailSectionToggle(event) {
    const dataset = event && event.currentTarget ? event.currentTarget.dataset : {};
    const section = dataset && dataset.section ? dataset.section : "";
    if (!section) return;

    const modal = this.data.detailModal || createDetailModalState();
    const expanded = Object.assign({ groups: true, fields: false }, modal.expandedSections || {});
    expanded[section] = !expanded[section];
    this.setData({ "detailModal.expandedSections": expanded });
  },

  handleMemberDetailMaskTap() {
    this.closeMemberDetail();
  },

  handleMemberDetailClose() {
    this.closeMemberDetail();
  },

  closeMemberDetail() {
    this.setData({ detailModal: createDetailModalState() });
  },

  handleMemberDetailDelete() {
    if (!this.data.isPublisher) return;
    const modal = this.data.detailModal || createDetailModalState();
    if (!modal.visible || modal.loading || modal.deleting) return;

    const registrant = modal.registrant || {};
    const openID = registrant.openID || "";
    if (!openID) return;

    const activityID = this.data.activityID;
    if (!activityID) return;

    const groupIDs = [];
    if (registrant.groupID) groupIDs.push(String(registrant.groupID));
    if (Array.isArray(registrant.registrationGroups)) {
      registrant.registrationGroups.forEach(item => {
        const id = item.groupID || item.GroupID || item.groupId || item.GroupId || "";
        if (id) groupIDs.push(String(id));
      });
    }
    const primaryGroupID = groupIDs.length > 0 ? groupIDs[0] : "";

    wx.showModal({
      title: "删除报名",
      content: "确定要删除该报名吗？",
      confirmText: "删除",
      confirmColor: "#f87171",
      cancelText: "取消",
      success: res => {
        if (!res || !res.confirm) return;
        this.setData({
          "detailModal.deleting": true,
          "detailModal.error": ""
        });

        this.callFunction({
          name: "deleteRegistrant",
          data: { activityID, deletedOpenID: openID, groupID: primaryGroupID },
          loadingTitle: "处理中..."
        })
          .then(res => {
            const payload = res && (res.result || res.data || res);
            if (!payload || !payload.success) {
              const message =
                (payload && (payload.error || payload.message)) || "操作失败，请稍后重试";
              this.setData({
                "detailModal.error": message
              });
              return;
            }

            if (this.data.mode === "registrants") {
              const updatedGroups = (this.data.groups || []).map(group => {
                const list = Array.isArray(group.registrants) ? group.registrants : [];
                const filtered = list.filter(item => item.openID !== openID);
                if (filtered.length === list.length) return group;
                const quota = typeof group.quota === "number" ? group.quota : 0;
                return Object.assign({}, group, {
                  registrants: filtered,
                  count: filtered.length,
                  countDisplay: quota > 0 ? `${filtered.length}/${quota}` : `${filtered.length}`
                });
              });

              const totalRegistrants = updatedGroups.reduce((sum, group) => {
                if (typeof group.count === "number") return sum + group.count;
                if (Array.isArray(group.registrants)) return sum + group.registrants.length;
                return sum;
              }, 0);

              this.setData({
                groups: updatedGroups,
                totalRegistrants,
                detailModal: createDetailModalState()
              });
            } else {
              const activeGroupID = this.data.activeGroupID;
              this.setData({ detailModal: createDetailModalState() });
              if (activeGroupID) {
                this.loadCheckInGroup(activeGroupID);
              }
            }
            wx.showToast({ title: "已删除报名", icon: "success" });
          })
          .catch(error => {
            const message = this.normalizeError(error, "操作失败，请稍后重试");
            this.setData({
              "detailModal.error": message
            });
          })
          .finally(() => {
            const currentModal = this.data.detailModal || {};
            if (currentModal && currentModal.visible) {
              this.setData({ "detailModal.deleting": false });
            }
          });
      }
    });
  },

  preventTouchMove() {}
});
